<template>
  <div id="kt_modal_scrollable_algorithm_desc" class="modal fade" tabindex="-1">
    <div class="modal-dialog modal-dialog-scrollable modal-lg">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title">算法说明</h5>

          <!--begin::Close-->
          <div
            class="btn btn-icon btn-sm btn-active-light-primary ms-2"
            data-bs-dismiss="modal"
            aria-label="Close"
          >
            <i class="ki-duotone ki-cross fs-2x">
              <span class="path1"></span>
              <span class="path2"></span>
            </i>
          </div>
          <!--end::Close-->
        </div>

        <div class="modal-body">
          <h3 id="月均和周均计算算法解释">月均和周均计算算法解释</h3>
          <p>
            你好！根据代码（EngineerMapper.xml 中的 SQL
            查询），我来详细解释一下月均（monthlyAvgCommits 和
            monthlyAvgChanges）和周均（weeklyAvgCommits 和
            weeklyAvgChanges）的计算算法。这些指标是基于工程师的提交历史数据（commit_log
            表）来统计的，目的是评估工程师的平均活跃度。计算发生在后端 SQL
            查询中，前端（EngineerTableWidget.vue）仅对结果进行格式化（使用
            <code>toFixed(0)</code> 取整）。
          </p>
          <h4 id="1-基础数据准备">1. <strong>基础数据准备</strong></h4>
          <ul>
            <li>
              <strong>总提交数 (allCommitCount)</strong>: 工程师所有提交记录的数量（COUNT(cl.id)）。
            </li>
            <li>
              <strong>总代码变化行数 (allTotalChanges)</strong>:
              所有提交的总变化行数（SUM(cl.total_changes)）。
            </li>
            <li>
              <strong>最早提交日期 (minDate)</strong>:
              工程师最早一次提交的日期（MIN(cl.authored_date)）。
            </li>
            <li>
              <strong>最晚提交日期 (maxDate)</strong>:
              工程师最晚一次提交的日期（MAX(cl.authored_date)）。
            </li>
            <li>
              <strong>过滤条件</strong>: 只考虑 commit_type = 1 且 total_changes &lt;= 10000
              的提交（可能是为了排除异常或合并提交）。
            </li>
            <li>如果没有提交记录（minDate 为 NULL），所有平均值直接返回 0。</li>
          </ul>
          <p>
            这些数据通过 WITH 子查询（stats）计算，关联了工程师表 (engineer)、邮箱表
            (engineer_email) 和提交日志表 (commit_log)。
          </p>

          <h4 id="2-月均算法-monthlyavgcommits-和-monthlyavgchanges">
            2. <strong>月均算法 (monthlyAvgCommits 和 monthlyAvgChanges)</strong>
          </h4>
          <ul>
            <li>
              <strong>公式</strong>:
              <ul>
                <li>
                  monthlyAvgCommits = allCommitCount / TIMESTAMPDIFF(MONTH, minDate, maxDate) （如果
                  minDate 不为空）
                </li>
                <li>
                  monthlyAvgChanges = allTotalChanges / TIMESTAMPDIFF(MONTH, minDate,
                  maxDate)（类似）
                </li>
              </ul>
            </li>
            <li>
              <strong>解释</strong>:
              <ul>
                <li>
                  计算工程师从最早提交到最晚提交的<strong>总月数</strong>（使用 MySQL 的
                  TIMESTAMPDIFF(MONTH, start, end)
                  函数，它返回两个日期之间的完整月差。例如，2023-01-15 到 2023-03-10 是 2 个月）。
                </li>
                <li>然后，用总提交数（或总变化行数）除以总月数，得到月平均值。</li>
                <li>
                  <strong>边界处理</strong>: 如果总月数为 0（例如 minDate 和 maxDate
                  相同，或没有提交），则返回 0（通过 CASE WHEN 避免除零错误）。
                </li>
              </ul>
            </li>
            <li>
              <strong>示例</strong>:
              <ul>
                <li>
                  假设工程师有 100 次提交，最早日期 2023-01-01，最晚 2023-12-31，总月数 =
                  11（1月到12月差 11 个月？注意：TIMESTAMPDIFF(MONTH)
                  计算的是完整月差，如果是同月则为0）。
                </li>
                <li>月均提交 = 100 / 11 ≈ 9.09（前端取整为 9）。</li>
              </ul>
            </li>
            <li>
              <strong>潜在问题</strong>:
              这个算法假设整个时间跨度都是活跃的，但如果工程师中间有几个月没提交，会低估平均值（因为总月数包括非活跃月）。如果需要更精确，可以修改为只计算有提交的月份。
            </li>
          </ul>

          <h4 id="3-周均算法-weeklyavgcommits-和-weeklyavgchanges">
            3. <strong>周均算法 (weeklyAvgCommits 和 weeklyAvgChanges)</strong>
          </h4>
          <ul>
            <li>
              <strong>公式</strong>:
              <ul>
                <li>
                  weeklyAvgCommits = allCommitCount / (TIMESTAMPDIFF(DAY, minDate, maxDate) / 7.0)
                  （如果 minDate 不为空）
                </li>
                <li>
                  weeklyAvgChanges = allTotalChanges / (TIMESTAMPDIFF(DAY, minDate, maxDate) / 7.0)
                  （类似）
                </li>
              </ul>
            </li>
            <li>
              <strong>解释</strong>:
              <ul>
                <li>
                  先计算从最早到最晚提交的<strong>总天数</strong>（TIMESTAMPDIFF(DAY, minDate,
                  maxDate) 返回天数差）。
                </li>
                <li>
                  然后，将总天数除以 7.0 得到<strong>总周数</strong>（使用浮点除法以支持小数周）。
                </li>
                <li>最后，用总提交数（或总变化行数）除以总周数，得到周平均值。</li>
                <li><strong>边界处理</strong>: 同月均，如果总天数为 0，则返回 0。</li>
              </ul>
            </li>
            <li>
              <strong>示例</strong>:
              <ul>
                <li>
                  假设 100 次提交，最早 2023-01-01，最晚 2023-01-31，总天数 = 30，天 / 7 ≈ 4.285
                  周。
                </li>
                <li>周均提交 = 100 / 4.285 ≈ 23.33（前端取整为 23）。</li>
              </ul>
            </li>
            <li>
              <strong>潜在问题</strong>:
              类似月均，会包括非活跃周，导致平均值偏低。总周数使用浮点（/7.0），所以结果更精确，但前端取整可能会丢失小数。
            </li>
          </ul>

          <h4 id="4-前端处理">4. <strong>前端处理</strong></h4>
          <ul>
            <li>
              在 EngineerTableWidget.vue 的 loadData 函数中，对这些平均值使用
              <code>toFixed(0)</code> 取整（例如 9.09 变为 9）。
            </li>
            <li>这确保表格显示整型数字，便于阅读。</li>
          </ul>

          <h4 id="5-改进建议">5. <strong>改进建议</strong></h4>
          <ul>
            <li>
              <strong>更准确的活跃期计算</strong>:
              当前算法使用总时间跨度，可能不准。如果想只计算活跃月/周，可以修改 SQL
              为统计实际有提交的月/周数量（例如 GROUP BY MONTH/YEAR 或 WEEK）。
            </li>
            <li>
              <strong>性能</strong>: 这个查询使用递归 CTE（WITH
              RECURSIVE）来构建部门路径，如果数据量大，可能慢。可以考虑预计算或缓存。
            </li>
            <li>
              <strong>测试</strong>: 你可以运行 SQL 片段测试具体数据，例如 SELECT
              TIMESTAMPDIFF(MONTH, '2023-01-01', '2023-12-31') 返回 11。
            </li>
          </ul>
          <p>
            如果这个解释不够清楚，或者你想修改算法（例如调整为活跃月计算），告诉我更多细节，我可以帮你优化代码！
          </p>
        </div>

        <div class="modal-footer">
          <button type="button" class="btn btn-light" data-bs-dismiss="modal">关闭</button>
        </div>
      </div>
    </div>
  </div>
</template>
